#ifndef XGAME_OBJECT
#define XGAME_OBJECT
#include "GameCore\DXDeviceWP8.h"
#include "Box2D\Common\b2Math.h"
#include "GameCore\Bound.h"
#include "GameCore\Texture.h"
#include "GameCore\Sprite.h"

class GameObject
{
	friend class GameObjectFactory;
	friend class Map;
protected:
	Vector2f position;
	Vector2f move;
	float rotation;
	Sprite* sprite;
	SpriteAnimInstance* animInst;
	int frame;
	bool useAnim;
	bool destroyed;
	bool removed;
public:
	int hp;
	GameObject()
	{
		animInst = new SpriteAnimInstance();
		rotation = 0.0f;
		frame = 0;
		useAnim = false;
		destroyed = false;
		removed = false;
		hp = 1;
	}
	virtual ~GameObject()
	{
		SafeDelete(animInst);
	}
	virtual void Init();
	virtual void Render();
	virtual void Update(float timeDelta);
	virtual void Destroy()
	{
		destroyed = true;
	}
	void SetAnim(SpriteAnim* anim)
	{
		this->animInst->time = 0;
		this->animInst->currentFrame = 0;
		this->animInst->anim = anim;
	}
	b2Transform GetBox2DTransform()
	{
		return b2Transform(b2Vec2(position.x, position.y), b2Rot(rotation));
	}
	virtual BoundGroup* GetBodyRegion()
	{
		return sprite->GetFrame((useAnim == true)? animInst->currentFrame:frame)->boundGroups[BoundGroup::BG_TYPE_BODY];
	}
	virtual BoundGroup* GetDamageRegion()
	{
		return sprite->GetFrame((useAnim == true)? animInst->currentFrame:frame)->boundGroups[BoundGroup::BG_TYPE_WEAPON];
	}
	virtual bool CollisionCheckBodyRegion(BoundGroup* bg, b2Transform* transform)
	{
		return sprite->GetFrame((useAnim == true)? animInst->currentFrame:frame)->boundGroups[BoundGroup::BG_TYPE_BODY]->IsIntersectedWith(bg, &GetBox2DTransform(), transform);
	}
	virtual bool CollisionCheckWeaponRegion(BoundGroup* bg, b2Transform* transform)
	{
		return sprite->GetFrame((useAnim == true)? animInst->currentFrame:frame)->boundGroups[BoundGroup::BG_TYPE_WEAPON]->IsIntersectedWith(bg, &GetBox2DTransform(), transform);
	}
	void SetPosition(float x, float y)
	{
		position.x = x;
		position.y = y;
	}
	void SetSprite(Sprite *s)
	{
		sprite = s;
	}
	bool IsRemoved()
	{
		return removed;
	}
};

struct ShipInitialValue
{
	char* name;
	char* spriteName;
	//Sprite* sprite;
	int hp;
	int damage;
	bool active;
	GameObject* (*createFunction)();
	ShipInitialValue(const char* iName, const char* iSprite, const int iHp, const int iDamage)
	{
		name = new char[strlen(iName)+1];
		strcpy(name, iName);
		spriteName = new char[strlen(iSprite)+1];
		strcpy(spriteName, iSprite);
		hp = iHp;
		damage = iDamage;
		//sprite = NULL;
		active = false;
	}
	ShipInitialValue(const ShipInitialValue& src)
	{
		name = new char[strlen(src.name)+1];
		strcpy(name, src.name);
		spriteName = new char[strlen(src.spriteName)+1];
		strcpy(spriteName, src.spriteName);
		hp = src.hp;
		damage = src.damage;
//		sprite = src.sprite;
		active = src.active;
	}
	const ShipInitialValue& operator=( const ShipInitialValue& src )
	{
		name = new char[strlen(src.name)+1];
		strcpy(name, src.name);
		spriteName = new char[strlen(src.spriteName)+1];
		strcpy(spriteName, src.spriteName);
		hp = src.hp;
		damage = src.damage;
//		sprite = src.sprite;
		active = src.active;
		return *this;
	}
	~ShipInitialValue()
	{
		SafeDeleteArray(name);
		SafeDeleteArray(spriteName);
	}
};
class GameObjectFactory
{
public:
	static std::vector<ShipInitialValue> shipInitialValueList;
	static void LoadShipInitialValue(const char* data);
	static GameObject* CreateShipFromName(const char* name);
	//static void UpdateShipInitialValueResource();
	static void ActiveShipInitialValue(const char* name, bool active);
	static void ActiveAllShipInitialValue(bool active);
	static ShipInitialValue* GetShipInitialValueFromName(const char* name);
};
#endif